
// <copyright file="SharedReflectionInfo.cs" company="Subhadra Software Solutions">
//   
// </copyright>
// <summary>
//   The shared reflection info.
// </summary>

namespace SubhadraSolutions.Sharp.Utils.Reflection.Internal
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Reflection;

    using SubhadraSolutions.Sharp.Utils.Data.Helpers;
    using SubhadraSolutions.Sharp.Utils.Diagnostics.Performance;

    /// <summary>
    /// The shared reflection info.
    /// </summary>
    internal class SharedReflectionInfo
    {
        #region Static Fields

        /// <summary>
        /// The safe invoke method
        /// </summary>
        public static readonly MethodInfo SafeInvokeMethod = typeof(GeneralHelper).GetMethod("SafeInvoke", BindingFlags.Public | BindingFlags.Static);

        /// <summary>
        /// The times.
        /// </summary>
        internal static readonly string[] Times = { "Ticks", "Milliseconds", "Seconds", "Minutes", "Hours" };

        /// <summary>
        /// The array indexer get method.
        /// </summary>
        internal static readonly MethodInfo ArrayIndexerGetMethod = typeof(object[]).GetMethod("Get");

        /// <summary>
        /// The array indexer set method.
        /// </summary>
        internal static readonly MethodInfo ArrayIndexerSetMethod = typeof(object[]).GetMethod("Set");

        /// <summary>
        /// The convert to methods.
        /// </summary>
        internal static Dictionary<Type, MethodInfo> ConvertToMethods = new Dictionary<Type, MethodInfo>();

        /// <summary>
        /// The get value from data record method.
        /// </summary>
        internal static readonly MethodInfo GetValueFromDataRecordMethod = typeof(DataHelper).GetMethod("GetValueFromDataRecord", BindingFlags.Public | BindingFlags.Static);

        /// <summary>
        /// The list indexer get method
        /// </summary>
        internal static readonly MethodInfo PerfCounterListIndexerGetMethod = typeof(IList<PerfCounter>).GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(int) }, null);

        /// <summary>
        /// The object to string method.
        /// </summary>
        internal static MethodInfo ObjectToStringMethod = typeof(StringHelper).GetMethod("GetObjectAsString", BindingFlags.Static | BindingFlags.Public);

        /// <summary>
        /// The perf counter set raw value method.
        /// </summary>
        internal static readonly MethodInfo PerfCounterSetRawValueMethod = typeof(PerfCounter).GetMethod("set_RawValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(double) }, null);

        /// <summary>
        /// The perf counter set tag method.
        /// </summary>
        internal static readonly MethodInfo PerfCounterSetTagMethod = typeof(PerfCounter).GetMethod("set_Tag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new[] { typeof(object) }, null);

        /// <summary>
        /// The refresh counters method.
        /// </summary>
        internal static readonly MethodInfo RefreshCountersMethod = typeof(IRefreshCounters).GetMethod("RefreshCounters");

        /// <summary>
        /// The text writer write methods.
        /// </summary>
        internal static readonly Dictionary<Type, MethodInfo> TextWriterWriteMethods = new Dictionary<Type, MethodInfo>();

        /// <summary>
        /// The time methods.
        /// </summary>
        internal static readonly MethodInfo[] TimeMethods = new MethodInfo[5];

        /// <summary>
        /// The compare method.
        /// </summary>
        internal static readonly MethodInfo CompareMethod = typeof(GeneralHelper).GetMethod("Compare", BindingFlags.Static | BindingFlags.Public);

        /// <summary>
        /// The enum parse method
        /// </summary>
        //internal static readonly MethodInfo EnumParseMethod = typeof(Enum).GetMethod("Parse", BindingFlags.Static | BindingFlags.Public);


        #endregion Static Fields

        #region Constructors and Finalizers

        /// <summary>
        /// Initializes static members of the <see cref="SharedReflectionInfo"/> class.
        /// </summary>
        static SharedReflectionInfo()
        {
            populateTimeMethods();
            populateConvertToMethods();
            populateTextWriterWriteMethods();
        }

        #endregion Constructors and Finalizers

        #region Methods

        /// <summary>
        /// The populate convert to methods.
        /// </summary>
        private static void populateConvertToMethods()
        {
            Type t = typeof(Convert);
            MethodInfo[] methods = t.GetMethods();
            foreach (MethodInfo method in methods)
            {
                if (method.IsStatic)
                {
                    ParameterInfo[] parameters = method.GetParameters();
                    if (parameters.Length == 1 && parameters[0].ParameterType == typeof(String))
                    {
                        ConvertToMethods.Add(method.ReturnType, method);
                    }
                }
            }
        }

        /// <summary>
        /// The populate text writer write methods.
        /// </summary>
        private static void populateTextWriterWriteMethods()
        {
            MethodInfo[] methods = typeof(TextWriter).GetMethods();
            foreach (MethodInfo method in methods)
            {
                if (method.ReturnType == typeof(void) && method.Name == "Write")
                {
                    ParameterInfo[] parameters = method.GetParameters();
                    if (parameters.Length == 1)
                    {
                        TextWriterWriteMethods.Add(parameters[0].ParameterType, method);
                    }
                }
            }
        }

        /// <summary>
        /// The populate time methods.
        /// </summary>
        private static void populateTimeMethods()
        {
            TimeMethods[0] = typeof(TimeSpan).GetProperty("Ticks").GetGetMethod();
            for (int i = 1; i < 5; i++)
            {
                TimeMethods[i] = typeof(TimeSpan).GetProperty("Total" + Times[i]).GetGetMethod();
            }
        }

        #endregion Methods
    }
}
